package com.bah.tract.client.workstore.jira;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.prefs.Preferences;

import com.atlassian.jira.rpc.soap.client.JiraSoapService;
import com.atlassian.jira.rpc.soap.client.RemoteException;
import com.atlassian.jira.rpc.soap.client.RemoteIssue;
import com.atlassian.jira_soapclient.SOAPSession;
import com.bah.tract.client.Constants;
import com.bah.tract.client.ErrorHandler;
import com.bah.tract.client.workstore.TaskProvider;
import com.bah.tract.security.PasswordEncryptor;
import com.bah.tract.service.StringProperty;
import com.bah.tract.service.Task;

public class JiraTaskProvider implements TaskProvider {

	private final String serviceUrl;
	private final String projectKey;

	private final String user;
	private String password;
	private final long mStoreId;

	public JiraTaskProvider(final PasswordEncryptor encryptor,
			final Preferences preferences,
			final Map<String, Object> properties, final long storeId) {
		serviceUrl = (String) properties.get("serviceUrl");
		projectKey = (String) properties.get("projectKey");
		user = preferences.get(Constants.JIRA_ID_PREF, null);
		try {
			password = encryptor.decrypt(preferences.get(
					Constants.JIRA_PASS_PREF, null));
		} catch (final GeneralSecurityException e) {
			ErrorHandler.handleError(e);
		}
		mStoreId = storeId;
	}

	@Override
	public final List<Task> getTasks() {
		try {
			final SOAPSession soapSession = new SOAPSession(new URL(serviceUrl));

			soapSession.connect(user, password);

			// the JIRA SOAP Service and authentication token are used to make
			// authentication calls
			final JiraSoapService jiraService = soapSession
					.getJiraSoapService();
			final String authToken = soapSession.getAuthenticationToken();

			final RemoteIssue[] issues = jiraService.getIssuesFromJqlSearch(
					authToken, "project = " + projectKey
							+ " AND resolution = Unresolved AND assignee = "
							+ user + " ORDER BY key ASC", Integer.MAX_VALUE);
			final List<Task> tasks = new ArrayList<Task>();
			for (final RemoteIssue issue : issues) {
				final Task t = new Task();
				t.setDescription(issue.getDescription());
				t.setLabel(issue.getKey() + " " + issue.getSummary());
				t.setType("JiraIssue");
				t.setStoreId(mStoreId);
				t.getIdentifyingProperty().add(
						new StringProperty("issueNumber", issue.getKey()));
				t.getDescriptiveProperty().add(
						new StringProperty("serviceUrl", serviceUrl));

				tasks.add(t);
			}
			return tasks;
		} catch (final RemoteException e) {
			ErrorHandler.handleError(e);
		} catch (final MalformedURLException e) {
			ErrorHandler.handleError(e);
		} catch (final java.rmi.RemoteException e) {
			ErrorHandler.handleError(e);
		}
		return null;
	}

}
